home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 101-125 / disk_107 / prosuite / fileio / volname.c < prev   
C/C++ Source or Header  |  1992-05-06  |  7KB  |  255 lines

  1.  
  2. /* *** volname.c ************************************************************
  3.  *
  4.  * File IO Suite  --  Volume Name Construction Routines
  5.  *     from Book 1 of the Amiga Programmers' Suite by RJ Mical
  6.  *
  7.  * Copyright (C) 1986, 1987, Robert J. Mical
  8.  * All Rights Reserved.
  9.  *
  10.  * Created for Amiga developers.
  11.  * Any or all of this code can be used in any program as long as this
  12.  * entire copyright notice is retained, ok?  Thanks.
  13.  *
  14.  * The Amiga Programmer's Suite Book 1 is copyrighted but freely distributable.
  15.  * All copyright notices and all file headers must be retained intact.
  16.  * The Amiga Programmer's Suite Book 1 may be compiled and assembled, and the 
  17.  * resultant object code may be included in any software product.  However, no 
  18.  * portion of the source listings or documentation of the Amiga Programmer's 
  19.  * Suite Book 1 may be distributed or sold for profit or in a for-profit 
  20.  * product without the written authorization of the author, RJ Mical.
  21.  * 
  22.  * HISTORY      NAME            DESCRIPTION
  23.  * -----------  --------------  --------------------------------------------
  24.  * 27 Sep 87    RJ              Leave VolumeIndex alone as much as possible.
  25.  *                              Also, after building a new volume table, try 
  26.  *                              to look up the old volume name among the 
  27.  *                              new volume entries and set VolumeIndex 
  28.  *                              if possible.
  29.  * 4 Feb 87     RJ              Real release
  30.  * 12 Aug 86    RJ >:-{)*       Prepare (clean house) for release
  31.  * 3 May 86     =RJ Mical=      Fix prop gadget for both 1.1 and 1.2
  32.  * 1 Feb 86     =RJ Mical=      Created this file.
  33.  *
  34.  * *********************************************************************** */
  35.  
  36.  
  37. #define FILEIO_SOURCEFILE
  38. #include "fileio.h"
  39. #include <libraries/dosextens.h>
  40.  
  41.  
  42. /* Lattice doesn't accept the ID_DOS_DISK which looks like this:
  43.  * #define ID_DOS_DISK ('DOS\0')
  44.  * so I make up my own.
  45.  */
  46. #define X_ID_DOS_DISK (((LONG)'D'<<24)|((LONG)'O'<<16)|('S'<<8)|('\0'))
  47.  
  48.  
  49. BOOL DOSDisk(device)
  50. struct DeviceList *device;
  51. /* This little routine dips its gnarled toes directly into the 
  52.  * scary murky depths of AmigaDOS interior.
  53.  * If it survives, it returns TRUE or FALSE depending on whether or
  54.  * the specified device is a DOS disk.
  55.  * Jeez, Look at the structure names in this routine!  Whew!  You almost
  56.  * gotta be a computer scientist to understand this stuff.
  57.  */
  58. {
  59.     struct MsgPort *port;
  60.     BOOL result;
  61.     struct InfoData *info;
  62.     struct StandardPacket *packet;
  63.  
  64.  
  65.     result = FALSE;
  66.  
  67.     /* Allocate the data structures required to communicate with AmigaDOS */
  68.     info = (struct InfoData *)AllocMem(sizeof(struct InfoData), MEMF_CLEAR);
  69.     packet = (struct StandardPacket *)AllocMem(sizeof(struct StandardPacket),
  70.             MEMF_CLEAR);
  71.  
  72.     /* Grab us a message port for the reply from DOS */
  73.     port = CreatePort(NULL, 0);
  74.  
  75.     if (port && info && packet)
  76.         {
  77.         /* OK, everything is set so here we go! */
  78.  
  79.         /* Set up the StandardPacket's Exec message */
  80.         packet->sp_Msg.mn_Node.ln_Type = NT_MESSAGE;
  81.         packet->sp_Msg.mn_Node.ln_Name = (char *)&packet->sp_Pkt;
  82.         packet->sp_Msg.mn_ReplyPort = port;
  83.  
  84.         /* Set up the StandardPacket's DOS data */
  85.         packet->sp_Pkt.dp_Link = &packet->sp_Msg;
  86.         packet->sp_Pkt.dp_Type = ACTION_DISK_INFO;
  87.         packet->sp_Pkt.dp_Arg1 = ((LONG)info >> 2);
  88.         packet->sp_Pkt.dp_Port = port;
  89.  
  90.         /* Now, ask the device whether or not it's a DOS disk */
  91.         PutMsg(device->dl_Task, &packet->sp_Msg);
  92.         /* zzz */
  93.         WaitPort(port);
  94.  
  95.         /* Well? */
  96.         if (info->id_DiskType == X_ID_DOS_DISK) result = TRUE;
  97.         }
  98.  
  99.     if (port) DeletePort(port);
  100.     if (info) FreeMem(info, sizeof(struct InfoData));
  101.     if (packet) FreeMem(packet, sizeof(struct StandardPacket));
  102.  
  103.     return(result);
  104. }
  105.  
  106.  
  107.  
  108. VOID BuildVolumeTable(fileio)
  109. struct FileIOSupport *fileio;
  110. /* This routine builds an alphabetically-sorted list of all active volumes.
  111.  * The names can be either the device names or the volume names, depending
  112.  * on whether you set USE_VOLUME_NAMES.
  113.  */
  114. {
  115.     struct DosInfo *dosinfo;
  116.     struct DeviceList *masterlist, *devlist, *worklist;
  117.     struct MsgPort *handler;
  118.     LONG yuck;
  119.     UBYTE *nameptr, *textptr;
  120.     UBYTE len;
  121.     SHORT i;
  122.     struct Remember **key, *localkey, *keyptr;
  123.  
  124.     if (DosBase == NULL) return;
  125.  
  126.     key = &fileio->VolumeKey;
  127.     FreeRemember(key, TRUE);
  128.     localkey = NULL;
  129.  
  130. /* FORMERLY:  fileio->VolumeCount = fileio->VolumeIndex = 0;
  131.  * Instead, try leaving index where it was, clipping as needed at the end
  132.  */
  133.     fileio->VolumeCount = 0;
  134.  
  135.     /* First, feel through from DosBase down to the device list, dancing
  136.      * all the while with the bcpl pointers.
  137.      */
  138.     yuck = (LONG)((struct RootNode *)DosBase->dl_Root)->rn_Info;
  139.     dosinfo = (struct DosInfo *)(yuck << 2);    /* reality pointer */
  140.     yuck = (LONG)dosinfo->di_DevInfo;
  141.     masterlist = (struct DeviceList *)(yuck << 2);    /* reality pointer */
  142.  
  143.     devlist = masterlist;
  144.  
  145.  
  146.     while (devlist)
  147.         {
  148.         /* First, find each device that's active (dl_Task is not NULL) */
  149.         if ((devlist->dl_Type == DLT_DEVICE) && (devlist->dl_Task))
  150.             {
  151.             /* OK, got a device.  Now ask it if it's a DOS disk. */
  152.             if (NOT DOSDisk(devlist)) goto NEXT_DEVICE;
  153.  
  154.             /* OK, got a device that's a DOS disk.  Now find the name.
  155.              * If USE_VOLUME_NAMES is clear, use the device name,
  156.              * else look up the volume name.
  157.              */
  158.             nameptr = (UBYTE *)devlist->dl_Name;
  159.             if (FlagIsSet(fileio->Flags, USE_VOLUME_NAMES))
  160.                 {
  161.                 /* Use the handler for this volume to find the matching device */
  162.                 handler = (struct MsgPort *)devlist->dl_Task;
  163.  
  164.                 worklist = masterlist;
  165.                 while (worklist)
  166.                     {
  167.                     if ((worklist->dl_Type == DLT_VOLUME)
  168.                             && (worklist->dl_Task == handler))
  169.                         {
  170.                         nameptr = (UBYTE *)worklist->dl_Name;
  171.                         goto GOT_NAME;
  172.                         }
  173.  
  174.                     yuck = worklist->dl_Next;
  175.                     worklist = (struct DeviceList *)(yuck << 2);
  176.                     }
  177.                 /* If we get to the end of this loop and fall out, then what?  
  178.                  * Got an active device but no matching volume?  OK.
  179.                  */
  180.                 }
  181.  
  182. GOT_NAME:
  183.             yuck = (LONG)nameptr;
  184.             nameptr = (UBYTE *)(yuck << 2);
  185.             len = *nameptr++;
  186.  
  187.             if ((textptr = AllocRemember(&localkey, len + 2, NULL)) == NULL)
  188.                 {
  189.                 Alert(ALERT_OUTOFMEM, NULL);
  190.                 goto DEVICES_DONE;
  191.                 }
  192.  
  193.             fileio->VolumeCount++;
  194.             for (i = 0; i < len; i++) *textptr++ = *nameptr++;
  195.             *textptr++ = ':';
  196.             *textptr = '\0';
  197.             MakeEntry(localkey->Memory, key, NULL);
  198.             }
  199.  
  200. NEXT_DEVICE:
  201.         yuck = devlist->dl_Next;
  202.         devlist = (struct DeviceList *)(yuck << 2);
  203.         }
  204.  
  205.  
  206. DEVICES_DONE:
  207.  
  208.     FreeRemember(&localkey, TRUE);
  209.  
  210.     /* Safety measure */
  211.     if (fileio->VolumeIndex >= fileio->VolumeCount)
  212.         fileio->VolumeIndex = fileio->VolumeCount - 1;
  213.  
  214.     keyptr = fileio->VolumeKey;
  215.     nameptr = &fileio->DiskName[0];
  216.     i = 0;
  217.     while (keyptr)
  218.         {
  219.         if (StringsEqual(keyptr->Memory, nameptr))
  220.             {
  221.             fileio->VolumeIndex = i;
  222.             goto DONE;
  223.             }
  224.         keyptr = keyptr->NextRemember;
  225.         i++;
  226.         }
  227.  
  228.     fileio->VolumeIndex = 0;
  229.  
  230. DONE:    ;
  231. }
  232.  
  233.  
  234. UBYTE *CurrentVolumeName()
  235. /* This routine returns a pointer the name of the current volume */
  236. {
  237.     SHORT i;
  238.     struct Remember *remember;
  239.  
  240.     /* If there's no active volumes then return the "safe" volume name */
  241.     if (OpenReqFileIO->VolumeCount < 1)
  242.         return(&CurrentDiskString[0]);
  243.  
  244.     /* Safety measure */
  245.     if (OpenReqFileIO->VolumeIndex >= OpenReqFileIO->VolumeCount)
  246.         OpenReqFileIO->VolumeIndex = 0;
  247.  
  248.     /* Finally, look up the name */
  249.     remember = OpenReqFileIO->VolumeKey;
  250.     for (i = 0; i < OpenReqFileIO->VolumeIndex; i++)
  251.         remember = remember->NextRemember;
  252.     return(remember->Memory);
  253. }
  254.  
  255.